﻿using myBackupService.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace myBackupService.Common
{
    public class DirectoryToXmlGenerator
    {
        /// <summary>
        /// 高级目录转XML生成器
        /// </summary>
        /// <param name="directoryPath">目录路径</param>
        /// <param name="options">生成选项</param>
        /// <returns>XML文档</returns>
        public static XElement GenerateXmlFromDirectory(string pathId,string directoryPath,  DirectoryScanOptions options = null)
        {
            options = options ?? new DirectoryScanOptions();

            if (!Directory.Exists(directoryPath))
            {
                throw new DirectoryNotFoundException($"目录不存在: {directoryPath}");
            }
            
            var directoryInfo = new DirectoryInfo(directoryPath);
            var name = directoryInfo.Name;
            var path= BackupConfig.Instance.GetPath(pathId);
            if (path != directoryPath)
            {
                name = directoryPath.Replace(Directory.GetParent( path).FullName, "");
            }
            var root = new XElement("Directory");
            root.SetAttributeValue("PathId", pathId);
            root.SetAttributeValue("Name", name.TrimStart('\\'));
            root.SetAttributeValue("CreationTime", directoryInfo.CreationTime.ToString());
            root.SetAttributeValue("LastWriteTime", directoryInfo.LastWriteTime.ToString());

         
            ProcessDirectory(  pathId, directoryInfo, root, options);

            return  root;
        }

        private static void ProcessDirectory( string pathId,DirectoryInfo directoryInfo, XElement parentElement, DirectoryScanOptions options)
        {
            try
            {
                // 获取并过滤子目录
                DirectoryInfo[] subDirectories = directoryInfo.GetDirectories();
                if (options.ExcludeDirectories != null && options.ExcludeDirectories.Length > 0)
                {
                    subDirectories = subDirectories.Where(d => !options.ExcludeDirectories.Contains(d.Name)) .ToArray();
                }

                // 处理子目录
                if (options.IncludeDirectories)
                {
                    foreach (var subDirectory in subDirectories)
                    {
                        // 检查是否应该跳过此目录
                        if ((options.SkipHidden && (subDirectory.Attributes & FileAttributes.Hidden) != 0))
                            continue;

                        var dirElement = new XElement("Directory");
                        dirElement.SetAttributeValue("Name", subDirectory.Name.TrimStart('\\'));
                        dirElement.SetAttributeValue("CreationTime", subDirectory.CreationTime.ToString());
                        dirElement.SetAttributeValue("LastWriteTime", subDirectory.LastWriteTime.ToString());
                        parentElement.Add(dirElement);

                        // 递归处理（除非达到最大深度）
                        if (options.MaxDepth <= 0 || dirElement.Ancestors("Directory").Count() < options.MaxDepth)
                        {
                            ProcessDirectory( pathId,subDirectory, dirElement, options);
                        }
                    }
                }

                // 处理文件
                if (options.IncludeFiles)
                {
                    FileInfo[] files = directoryInfo.GetFiles();

                    // 根据扩展名过滤
                    if (options.IncludeExtensions != null && options.IncludeExtensions.Length > 0)
                    {
                        files = files .Where(f => options.IncludeExtensions.Contains(f.Extension.ToLower())).ToArray();
                    }

                    if (options.ExcludeExtensions != null && options.ExcludeExtensions.Length > 0)
                    {
                        files = files.Where(f => !options.ExcludeExtensions.Contains(f.Extension.ToLower())).ToArray();
                    }

                    foreach (var file in files)
                    {
                        // 检查是否应该跳过隐藏文件
                        if (options.SkipHidden && (file.Attributes & FileAttributes.Hidden) != 0)
                            continue;

                        var fileElement = new XElement("File");
                        fileElement.SetAttributeValue("Name", file.Name);
                        fileElement.SetAttributeValue("Size", file.Length);
                        fileElement.SetAttributeValue("CreationTime", file.CreationTime.ToString());
                        fileElement.SetAttributeValue("LastWriteTime", file.LastWriteTime.ToString());
                        parentElement.Add(fileElement);
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                var errorElement = new XElement("Error");
                errorElement.SetAttributeValue("Type", "UnauthorizedAccessException");
                errorElement.SetAttributeValue("Message", "访问被拒绝");
                errorElement.SetAttributeValue("Path", directoryInfo.FullName);
                parentElement.Add(errorElement);
            }
            catch (Exception ex)
            {
                var errorElement = new XElement("Error");
                errorElement.SetAttributeValue("Type", ex.GetType().Name);
                errorElement.SetAttributeValue("Message", ex.Message);
                errorElement.SetAttributeValue("Path", directoryInfo.FullName);
                parentElement.Add(errorElement);
            }
        }
    }
}
